import React, { useCallback, useEffect } from "react";
import { Button, Checkbox, Form, Input, Space, Typography } from "antd";
import { UserAddOutlined } from "@ant-design/icons";

import styles from "./Login.module.scss";
import { LoginType } from "../types";
import { Link } from "react-router-dom";
import { REGISTER_PATHNAME } from "../router";
import { loginService } from "../services/user";
import { useRequest, useTitle } from "ahooks";
import { setToken } from "../utils/user-token";
import useNavPage from "../hooks/useNavPage";
import { loginReducer } from "../store/userInfoReducer";
import { useDispatch } from "react-redux";
import { MD5 } from "crypto-js";

const { Title } = Typography;

const USERNAME_KEY = "USERNAME";
const PASSWORD_KEY = "PASSWORD";

function rememberUser(userName: string, password: string) {
  localStorage.setItem(USERNAME_KEY, userName);
  localStorage.setItem(PASSWORD_KEY, btoa(password));
  localStorage.setItem("remember", "true");
}

function deleteUserFromStorage() {
  localStorage.removeItem(USERNAME_KEY);
  localStorage.removeItem(PASSWORD_KEY);
  localStorage.removeItem("remember");
}

function getUserInfoFromStorage() {
  return {
    userName: localStorage.getItem(USERNAME_KEY),
    password: atob(localStorage.getItem(PASSWORD_KEY) || ""),
    remember: localStorage.getItem("remember"),
  };
}

const Login: React.FC = () => {
  useTitle("新问卷");
  useNavPage();
  const dispatch = useDispatch();
  const [form] = Form.useForm();
  const { loading, run } = useRequest(
    async (userName, password) => {
      return await loginService(userName, password);
    },
    {
      manual: true,
      onSuccess(res) {
        const { token, userId, userName, nickName, isAdmin } = res;
        setToken(token);
        dispatch(loginReducer({ userId, userName, nickName, isAdmin }));
      },
    }
  );

  useEffect(() => {
    setFrom();
  }, []);

  const setFrom = useCallback(() => {
    const { userName, password, remember } = getUserInfoFromStorage();
    if (!userName || !password || !remember) return;
    form.setFieldsValue({ userName, password, remember: Boolean(remember) });
  }, []);

  function onFinish(values: LoginType) {
    const { userName, password, remember } = values;
    run(userName, MD5(password.toString()).toString());
    if (remember) return rememberUser(userName, password.toString());
    deleteUserFromStorage();
  }

  return (
    <div className={styles.container}>
      <Space>
        <Title level={2}>
          <UserAddOutlined />
          &nbsp;用户登录
        </Title>
      </Space>
      <div>
        <Form
          labelCol={{ span: 6 }}
          wrapperCol={{ span: 16 }}
          initialValues={{ remember: false }}
          form={form}
          onFinish={onFinish}
        >
          <Form.Item
            label="用户名"
            name="userName"
            rules={[
              {
                required: true,
                message: "请输入用户名",
              },
              {
                type: "string",
                min: 2,
                max: 20,
                message: "字符长度在2-20之间",
              },
              {
                pattern: /^\w+$/,
                message: "只能输入数字、字母和下划线",
              },
            ]}
          >
            <Input allowClear />
          </Form.Item>
          <Form.Item
            label="密码"
            name="password"
            rules={[
              {
                required: true,
                message: "请输入密码",
              },
              {
                type: "string",
                min: 6,
                max: 20,
                message: "字符长度在6-20之间",
              },
            ]}
          >
            <Input.Password allowClear />
          </Form.Item>
          <Form.Item
            name="remember"
            valuePropName="checked"
            wrapperCol={{ offset: 6, span: 16 }}
          >
            <Checkbox>记住我</Checkbox>
          </Form.Item>
          <Form.Item wrapperCol={{ offset: 6, span: 16 }}>
            <Space>
              <Button type="primary" htmlType="submit" disabled={loading}>
                登录
              </Button>
              <Link to={REGISTER_PATHNAME}>注册新用户</Link>
            </Space>
          </Form.Item>
        </Form>
      </div>
    </div>
  );
};
export default Login;
